home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Software Vault: The Diamond Collection
/
The Diamond Collection (Software Vault)(Digital Impact).ISO
/
cdr44
/
rs232c16.zip
/
RS_DEMO.C
next >
Wrap
C/C++ Source or Header
|
1995-01-21
|
14KB
|
472 lines
/*
RS_DEMO: Terminal program to demonstrate most of the functions
available with RS232.C.
C. Karcher
*/
#include<conio.h>
#include<dos.h>
#include"rs232.c" /* full path for rs232.c */
#define BUF_SIZ 1024U /* 1K input and output buffers */
int initialize(char); /* Draws screen and initializes port */
void scr_update(int, int); /* Redefines text window and positions cursor */
void update(int); /* Decodes function keys and takes appropriate
action. Updates port status display */
int end_it(void); /* Restores text window and closes port prior
to exiting */
int loc_echo,add_nl; /* global operating mode flags */
char *in_buf,*out_buf; /* global buffer pointers */
int port_ok;
main()
{
extern int loc_echo,add_nl;
char buf1[BUF_SIZ],buf2[BUF_SIZ],in_lin[BUF_SIZ]; /* declare buffers */
int ip,i_cnt,c,k = 1;
ctrlbrk(end_it); /* set up control/break routine to insure port is
properly close */
in_buf = buf1; /* initialize global buffer pointers */
out_buf = buf2;
port_ok = initialize('1'); /* draw screen and initialize com port 1 */
loc_echo = add_nl = 0; /* init. misc. options */
/* become a terminal */
do{
if(port_ok > 0){ /* if port was initialized succesfully */
if((i_cnt = rs_inrcvd()) != 0){ /* anything in input buffer ? */
if(i_cnt > 1){ /* more than one byte, use rs_getstr to retrieve */
rs_getstr(i_cnt,in_lin);
}
else
*in_lin = rs_getbyt(); /* only one byte, use rs_getbyt */
for(ip = 0;ip < i_cnt;ip++){ /* display received bytes */
c = *(in_lin + ip);
putch(c);
if(add_nl && c == 0x0D) /* add NL to CR if applicable */
putch(0x0A);
}
}
update(0); /* in case any dynamics have changed */
}
if(rs_keyhit()){ /* any keyhits ? */
if((k = getch()) == 0){ /* if first byte 0, it's a function key */
k = getch(); /* get next byte and call update */
update(k);
}
else if(port_ok > 0){ /* otherwise if port's active, send the byte */
while(rs_sndbyt(k)){
if(rs_keyhit()){
k = getch();
if(k == 27)
break;
else
ungetch(k);
}
}
if(loc_echo){ /* display it if local echo on */
putch(k);
if(add_nl && k == 0x0D) /* add NL to CR if applicable */
putch(0x0A);
}
}
}
}while(k != 27); /* fall out if ESC */
end_it();
return 0;
}
void update(int key)
{
int port_update,x_save,y_save,tmp_i;
unsigned tmp_u;
extern int loc_echo,add_nl;
extern char *in_buf,*out_buf;
long baud[] = {110L,300L,600L,1200L,2400L,4800L,9600L,19200L,
38400L,57600L,115200L};
char parity[] = "NEOSM";
char *flow_str[] = {"None","XON/XOFF","CTS","DSR","RI","DCD"};
char *flwstat_str[] = {"Output Enabled","Output Disabled"};
char *line_str[] = {"Off","On"};
char *error_str[] = {"None","Break Detected","Framing Error",
"Parity Error","Rcv Data Overrun",
"Rcv Buffer Overflow"};
static struct{ /* static struct to hold user selectable characteristics */
char port;
int speed;
int par;
char dbits;
char sbits;
int flw_cnt;
int dtr;
int rts;
int loc_echo;
int add_nl;
}select = {'1',4,0,'8','1',RS_FLWOFF,0,0,0,0};
static struct{ /* static struct to hold dynamic statistics */
int flow_stat;
int mod_stat;
unsigned rcv_buf;
unsigned xmit_buf;
int error;
}dynamic;
port_update = 0; /* flag to indicate whether or not port should be closed
and reopened with new parameters */
/* Determine action from key code if one was sent. If port is inactive
except only command to change port number */
if(key != 0 && (port_ok > 0 || key == 0x3B)){
switch(key){
case 0x3B: /* F1 key - port ID */
if(++select.port > '4')
select.port = '1';
select.speed = 4;
select.par = 0;
select.dbits = '8';
select.sbits = '1';
port_ok = initialize(select.port);
break;
case 0x3C: /* F2 key - baud rate */
if(++select.speed > 10)
select.speed = 0;
port_update = 1;
scr_update(25,1);
cprintf("%-6ld",baud[select.speed]);
scr_update(0,0);
break;
case 0x3D: /* F3 key - parity */
if(++select.par > 4)
select.par = 0;
port_update = 1;
scr_update(44,1);
putch(parity[select.par]);
scr_update(0,0);
break;
case 0x3E: /* F4 key - data bits */
if(++select.dbits > '8')
select.dbits = '7';
port_update = 1;
scr_update(61,1);
putch(select.dbits);
scr_update(0,0);
break;
case 0x3F: /* F5 key - stop bits */
if(++select.sbits > '2')
select.sbits = '1';
port_update = 1;
scr_update(78,1);
putch(select.sbits);
scr_update(0,0);
break;
case 0x40: /* F6 key - Set Flow Control */
if(++select.flw_cnt > 5)
select.flw_cnt = 0;
switch(select.flw_cnt){
case 0:
rs_setflow(RS_FLWOFF);
break;
case 1:
rs_setflow(RS_FLWXON,RS_XON,RS_XOFF);
break;
case 2:
rs_setflow(RS_FLWHDW,RS_FLWCTS);
break;
case 3:
rs_setflow(RS_FLWHDW,RS_FLWDSR);
break;
case 4:
rs_setflow(RS_FLWHDW,RS_FLWRI);
break;
case 5:
rs_setflow(RS_FLWHDW,RS_FLWDCD);
break;
}
scr_update(21,3);
cprintf("%-8s",flow_str[select.flw_cnt]);
scr_update(0,0);
break;
case 0x41: /* F7 key - Clear Xmit buffer */
rs_clrout();
break;
case 0x42: /* F8 key - Clear Rcv buffer */
rs_clrin();
break;
case 0x43: /* F9 - toggle DTR */
if(select.dtr == 0){
select.dtr = 1;
rs_modctrl(RS_WRTMCR,RS_MCRDTR,RS_LINON);
}
else{
select.dtr = 0;
rs_modctrl(RS_WRTMCR,RS_MCRDTR,RS_LINOFF);
}
scr_update(10,5);
cprintf("%-3s",line_str[select.dtr]);
scr_update(0,0);
break;
case 0x44: /* F10 - toggle RTS */
if(select.rts == 0){
select.rts = 1;
rs_modctrl(RS_WRTMCR,RS_MCRRTS,RS_LINON);
}
else{
select.rts = 0;
rs_modctrl(RS_WRTMCR,RS_MCRRTS,RS_LINOFF);
}
scr_update(24,5);
cprintf("%-3s",line_str[select.rts]);
scr_update(0,0);
break;
case 0x54: /* sh/F1 key - local echo */
if(select.loc_echo == 1){
select.loc_echo = 0;
loc_echo = 0; /* update global variable */
}
else{
select.loc_echo = 1;
loc_echo = 1; /* update global variable */
}
scr_update(47,5);
cprintf("%-3s",line_str[select.loc_echo]);
scr_update(0,0);
break;
case 0x55: /* sh/F2 key - add newline to carriage return */
if(select.add_nl == 1){
select.add_nl = 0;
add_nl = 0; /* update global variable */
}
else{
select.add_nl = 1;
add_nl = 1; /* update global variable */
}
scr_update(77,5);
cprintf("%-3s",line_str[select.add_nl]);
scr_update(0,0);
break;
case 0x56: /* sh/F3 key - send break */
rs_break();
break;
case 0x57: /* sh/F4 key - send XON */
rs_setflow(RS_FLWINS,RS_XON);
break;
case 0x58: /* sh/F5 key - send XOFF */
rs_setflow(RS_FLWINS,RS_XOFF);
}
}
if(port_ok <= 0) /* don't continue if port is invalid */
return;
if(port_update){ /* new port parameters - close and reopen port */
rs_close();
select.flw_cnt = 0;
scr_update(21,3);
cprintf("%-8s",flow_str[select.flw_cnt]);
scr_update(0,0);
rs_initport(select.port,select.speed[baud],parity[select.par],
select.dbits,select.sbits,BUF_SIZ,in_buf,BUF_SIZ,out_buf);
}
/* check for changed flow control status */
if((tmp_i = rs_setflow(RS_FLWSTAT)) != dynamic.flow_stat){
dynamic.flow_stat = tmp_i;
scr_update(26,9);
cprintf("%-15s",flwstat_str[dynamic.flow_stat]);
scr_update(0,0);
}
/* check for modem status change */
tmp_i = rs_modctrl(RS_GETMSR);
if(tmp_i & 0x0F){ /* if any change bits are set */
if(tmp_i & RS_CTSCHG){ /* CTS change bit set? */
scr_update(47,9);
/* "(tmp_i & RS_CTSSTE) == RS_CTSSTE" equates to one if CTS bit
is on, otherwise, equates to 0 */
cprintf("%-3s",line_str[(tmp_i & RS_CTSSTE) == RS_CTSSTE]);
scr_update(0,0);
}
if(tmp_i & RS_DSRCHG){ /* DSR change bit set? */
scr_update(56,9);
cprintf("%-3s",line_str[(tmp_i & RS_DSRSTE) == RS_DSRSTE]);
scr_update(0,0);
}
if(tmp_i & RS_RICHG){ /* RI change bit set? */
scr_update(64,9);
cprintf("%-3s",line_str[(tmp_i & RS_RISTE) == RS_RISTE]);
scr_update(0,0);
}
if(tmp_i & RS_DCDCHG){ /* DCD change bit set? */
scr_update(73,9);
cprintf("%-3s",line_str[(tmp_i & RS_DCDSTE) == RS_DCDSTE]);
scr_update(0,0);
}
}
tmp_u = rs_inrcvd(); /* update "number of bytes in rcv buffer" if changed */
if(tmp_u != dynamic.rcv_buf){
dynamic.rcv_buf = tmp_u;
scr_update(20,10);
cprintf("%04u",dynamic.rcv_buf);
scr_update(0,0);
}
tmp_u = rs_outfre(); /* update "number of bytes in xmit buffer" if changed */
if(tmp_u != dynamic.xmit_buf){
dynamic.xmit_buf = tmp_u;
scr_update(40,10);
cprintf("%04u",BUF_SIZ - dynamic.xmit_buf);
scr_update(0,0);
}
/* Update error status if changed. Error status is displayed for
approx. 3 seconds */
tmp_i = rs_error();
if(tmp_i){
if(tmp_i & RS_BKDT)
tmp_i = 1;
else if(tmp_i & RS_FERR)
tmp_i = 2;
else if(tmp_i & RS_PERR)
tmp_i = 3;
else if(tmp_i & RS_ROER)
tmp_i = 4;
else if(tmp_i & RS_RBER)
tmp_i = 5;
dynamic.error = tmp_i;
scr_update(54,10);
cprintf("%-19s",error_str[tmp_i]);
scr_update(0,0);
rs_timer(RS_CLRTIM); /* clear timer */
}
else if(dynamic.error){
if(rs_timer(RS_GETTIM) > 50){ /* after about 3 seconds, clear error */
dynamic.error = 0;
scr_update(54,10);
cprintf("%-19s",error_str[0]);
scr_update(0,0);
}
}
}
int initialize(char port)
{
int x,port_ok;
char *line_str[] = {"Off","On"};
char txt[] = " (F1)Port: (F2)Speed:2400 (F3)Parity:N (F4)Data "
"Bits:8 (F5)Stop Bits:1\r\n\n (F6)Flow Control:None "
" (F7)Clear Xmit Buffer (F8)Clear Rcv Buffer\r\n"
"\n (F9)DTR:Off (F10)RTS:Off (Sh/F1)Local Echo:Off (S"
"h/F2)Add NewLine to CR:Off\r\n\n (Sh/F3)Send Break "
"(Sh/F4)Send XON (Sh/F5)Send XOFF (ESC)End Program\r"
"\n\n Flow Control Status:Output Enabled CTS: "
"DSR: RI: DCD:\r\n Rcv Buffer:0000 X"
"mit Buffer:0000 Error:None";
extern char *in_buf,*outbuf;
window(1,1,80,25);
clrscr();
cprintf("%s",txt);
rs_close();
port_ok = rs_initport(port,RS_B2400,RS_NOPAR,RS_DBIT8,RS_SBIT1,
BUF_SIZ,in_buf,BUF_SIZ,out_buf);
gotoxy(12,1);
putch(port);
/* if port initialization OK, get and display modem status and control */
if(port_ok > 0){
x = rs_modctrl(RS_GETMSR);
gotoxy(47,9);
if(x & RS_CTSSTE)
cputs(line_str[1]);
else
cputs(line_str[0]);
gotoxy(56,9);
if(x & RS_DSRSTE)
cputs(line_str[1]);
else
cputs(line_str[0]);
gotoxy(64,9);
if(x & RS_RISTE)
cputs(line_str[1]);
else
cputs(line_str[0]);
gotoxy(73,9);
if(x & RS_DCDSTE)
cputs(line_str[1]);
else
cputs(line_str[0]);
/* set DTR and RTS off */
rs_modctrl(RS_WRTMCR,RS_MCRDTR | RS_MCRRTS,RS_LINOFF);
}
else{ /* if port initialization not OK, display message */
gotoxy(14,1);
cprintf("%-65s","UNAVAILABLE");
}
gotoxy(1,8);
for(x = 0;x < 80;x++)
putch(196);
gotoxy(1,11);
for(x = 0;x < 80;x++)
putch(196);
window(1,12,80,25);
return port_ok; /* value returned by rs_initport */
}
void scr_update(int x, int y)
{
static int x_sav,y_sav;
/* If x != 0, save current cursor position, relocate cursor to new x
and y. If x = 0, set window back to terminal window and restore
old cursor postion */
if(x){
x_sav = wherex();
y_sav = wherey();
window(1,1,80,25);
gotoxy(x,y);
}
else{
window(1,12,80,25);
gotoxy(x_sav,y_sav);
}
}
int end_it(void)
{
window(1,1,80,25); /* restore window to full screen */
gotoxy(1,24); /* put cursor at bottom of window */
rs_close(); /* close the port */
return 1;
}